//
//  V2EyeTestViewController.swift
//  App_Vision
//
//  Created by Flutter on 2021/7/28.
//

import UIKit
import UICore
import SnapKit
import Leaf
import DeviceKit
import Standard
import Toast
import AVFoundation
import App_Common
import RxSwift
import RxCocoa

class EyeTestViewController: ViewController {
    
    
    lazy var viewModel = EyeTestViewModel()
    
    lazy var eView: EView = {
        EView(frame: CGRect.zero)
    }()
    
    lazy var visionLabel: UILabel = {
        UILabel()
            .leaf
            .textColor(.black)
            .text("4.3/0.1")
            .font(.boldSystemFont(ofSize: 24))
            .instance
    }()
    lazy var countLabel: UILabel = {
        UILabel()
            .leaf
            .text("正确:0 错误:0")
            .textAlignment(.center)
            .font(.systemFont(ofSize: 16))
            .textColor(#colorLiteral(red: 0.6, green: 0.6, blue: 0.6, alpha: 1))
            .instance
    }()
    
    lazy var leftEyeButton: UIButton = {
        UIButton(type: .custom)
            .leaf
            .titleColor(#colorLiteral(red: 0.6862745098, green: 0.6862745098, blue: 0.6862745098, alpha: 1), for: .normal)
            .titleColor(#colorLiteral(red: 0.8078431373, green: 0.3725490196, blue: 0.4980392157, alpha: 1), for: .selected)
            .image(UIImage.image(named: "vision_left_normal"), for: .normal)
            .image(UIImage.image(named: "vision_left_selected"), for: .selected)
            .titleText(title: "左眼", for: .normal)
//            .titleFont(font: .boldSystemFont(ofSize: 24))
            .instance
    }()
    
    lazy var rightEyeButton: UIButton = {
        UIButton(type: .custom)
            .leaf
            .titleColor(#colorLiteral(red: 0.6862745098, green: 0.6862745098, blue: 0.6862745098, alpha: 1), for: .normal)
            .titleColor(#colorLiteral(red: 0.1176470588, green: 0.6901960784, blue: 0.5921568627, alpha: 1), for: .selected)
            .image(UIImage.image(named: "vision_right_normal"), for: .normal)
            .image(UIImage.image(named: "vision_right_selected"), for: .selected)
            .titleText(title: "右眼", for: .normal)
//            .titleFont(font: .boldSystemFont(ofSize: 24))
            .instance
    }()
    
    lazy var glassAndDistanceLabel: UILabel = {
        UILabel()
            .leaf
            .backgroundColor(#colorLiteral(red: 0.9490196078, green: 0.9490196078, blue: 0.9490196078, alpha: 1))
            .textAlignment(.center)
            .textColor(#colorLiteral(red: 0.6, green: 0.6, blue: 0.6, alpha: 1))
            .text("裸眼 2.5m")
            .font(.systemFont(ofSize: 14))
            .instance
    }()
    
    // Rx
    let swipeTrigger = PublishSubject<EView.Direction>()
    let distanceTrigger = PublishSubject<Float>()
    let visionIndexTrigger = PublishSubject<Int>()
    let deltaVisionIndexTrigger = PublishSubject<Int>()
    let glassTrigger = PublishSubject<Bool>()
    let nextEyeTrigger = PublishSubject<Eye>()
}


// MARK: - Override
extension EyeTestViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        setupNavigationBar(title: String.localized("EyeTest.ViewController.Title"),canBack: true)
        
        setupUI()
        bindRx()
        
    }
    
}


// MARK: - UI

private extension EyeTestViewController {
    
    func setupUI() {
        
        
        addSwipeGestureRecognizers(directions: [.up,.down,.left,.right])
        
        eView.leaf.add(to: view).snp.makeConstraints {
            $0.center.equalToSuperview()
            $0.trailing.equalToSuperview().offset(-10)
            $0.leading.equalToSuperview().offset(10)
            $0.height.equalTo(eView.snp.width)
        }
        
        visionLabel.leaf.add(to: view).snp.makeConstraints {
            $0.centerX.equalToSuperview()
            $0.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(10)
        }
        
        
        glassAndDistanceLabel.layer.cornerRadius = 15
        glassAndDistanceLabel.layer.masksToBounds = true
        glassAndDistanceLabel.leaf.add(to: view).snp.makeConstraints {
            $0.centerX.equalToSuperview()
            $0.width.equalTo(100)
            $0.height.equalTo(30)
            $0.top.equalTo(visionLabel.snp.bottom).offset(30)
        }
    
        countLabel.leaf.add(to: view).snp.makeConstraints {
            $0.centerX.equalToSuperview()
            $0.top.equalTo(visionLabel.snp.bottom)
            $0.bottom.equalTo(glassAndDistanceLabel.snp.top)
        }
        

        leftEyeButton.leaf.add(to: view).snp.makeConstraints {
//            $0.centerY.equalTo(visionLabel.snp.bottom).offset(10)
            $0.top.equalTo(visionLabel.snp.top)
            $0.bottom.equalTo(glassAndDistanceLabel.snp.bottom)
            $0.leading.equalToSuperview()
            $0.trailing.equalTo(visionLabel.snp.leading)
        }
        rightEyeButton.leaf.add(to: view).snp.makeConstraints {
//            $0.centerY.equalTo(visionLabel.snp.bottom).offset(5)
            $0.top.equalTo(visionLabel.snp.top)
            $0.bottom.equalTo(glassAndDistanceLabel.snp.bottom)
            $0.leading.equalTo(visionLabel.snp.trailing)
            $0.trailing.equalToSuperview()
        }
        leftEyeButton.layoutButton(style: .Top, imageTitleSpace: 6)
        rightEyeButton.layoutButton(style: .Top, imageTitleSpace: 6)
        
        
        
        
    }
    
    func addSwipeGestureRecognizers(directions: [UISwipeGestureRecognizer.Direction]) {
        
        directions.forEach { direction in
            let swipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(swipe(sender:)))
            swipeGestureRecognizer.direction = direction
            view.addGestureRecognizer(swipeGestureRecognizer)
        }
    }
    
    @objc
    func swipe(sender: UISwipeGestureRecognizer)  {
        playSwipeSoundEffect()
        switch sender.direction {
        case .left:
            swipeTrigger.onNext(.Left)
        case .up:
            swipeTrigger.onNext(.Up)
        case .right:
            swipeTrigger.onNext(.Right)
        case .down:
            swipeTrigger.onNext(.Down)
        default: break
        }
    }
    
    func playSwipeSoundEffect(){
        guard let audioFile = VisionModular.bundle.path(forResource: "swipe", ofType: "mp3") else { return  }
        let soundUrl = URL(fileURLWithPath: audioFile)
        var soundId: SystemSoundID = 0
        AudioServicesCreateSystemSoundID(soundUrl as CFURL, &soundId)
        AudioServicesPlaySystemSound(soundId)
    }
    
}


// MARK: - RX
private extension EyeTestViewController {
    
    func bindRx() {
        
        viewModel.disposeBag = disposeBag
        let input = EyeTestViewModel.Input(
            swipe: swipeTrigger,
            next: nextEyeTrigger
//            distance: distanceTrigger,
//            glass: glassTrigger,
//            deltaVisionIndex: deltaVisionIndexTrigger,
//            visionIndex: visionIndexTrigger,
//            nextEye: nextEyeTrigger
        )
        let output = viewModel.transform(input: input)
        handleEyeTest(output.eyeTest)
        handleNext(output.next)
    }
    
    func handleEyeTest(_ eyeTest: BehaviorRelay<EyeTestModel>) {
        eyeTest.subscribe {[weak self] event in
            guard let self = self else { return }
            guard let element = event.element else { return }
            
            self.eView.rotate(direction: element.direction)
            
            let size = self.caculateSize(visionIndex: element.visionIndex, distance: element.distance)
            self.eView.resize(size: size)
            
            guard let newVision = VisionTable.getNewVision(index: element.visionIndex) else {
                self.view.makeToast(String.localized("EyeTest.ViewController.UnsupportDevice"), position: .center)
                return
            }
            guard let oldVision = VisionTable.getOldVision(index: element.visionIndex) else {
                self.view.makeToast(String.localized("EyeTest.ViewController.VisionTable.Error"), position: .center)
                return
            }
            self.visionLabel.text = "\(newVision)/\(oldVision)"
            
            let glassString = element.glass ? "眼镜" : "裸眼"
            if  element.distance < 1 {
                self.glassAndDistanceLabel.text = "\(glassString) \(Int(element.distance*100))cm"
            }else {
                self.glassAndDistanceLabel.text = "\(glassString) \(element.distance)m"
            }
           
            if  element.eye == .left {
                self.leftEyeButton.isSelected = true
                self.rightEyeButton.isSelected = false
                
            }else {
                self.leftEyeButton.isSelected = false
                self.rightEyeButton.isSelected = true
            }
            
            self.countLabel.text = "正确:\(element.right) 错误:\(element.wrong)"
            
            
            
        }.disposed(by: disposeBag)
    }
    
    func caculateSize(visionIndex: Int, distance: Float) -> CGSize{
        guard let ppi = Device.current.ppi else {
            self.view.makeToast(String.localized("EyeTest.ViewController.UnsupportDevice"), position: .center)
            return CGSize.zero
        }
        guard let vision = VisionTable.getOldVision(index: visionIndex) else {
            self.view.makeToast(String.localized("EyeTest.ViewController.VisionTable.Error"), position: .center)
            return CGSize.zero
        }
        let visionDegree = 1/((vision*60.0)*(180/Float.pi))
        let size = tan(visionDegree)*distance*1000.0
        let pixel = CGFloat((size*Float(ppi))*5/(2*25.4))
        return CGSize(width: pixel, height: pixel)
    }
    
    func handleNext(_ next: BehaviorRelay<EyeTestResult>) {
        
        next.subscribe { [weak self] event in
            guard let self = self else { return }
            guard let result = event.element else { return }
            if result.leftVisionIndex != nil || result.rightVisionIndex != nil {
                let resultVC = EyeTestResultViewController()
                resultVC.result = result
                resultVC.nextEyeTrigger.asObserver().bind(to: self.nextEyeTrigger).disposed(by: self.disposeBag)
                self.navigationController?.pushViewController(resultVC, animated: false)
            }
        }.disposed(by: disposeBag)

    }
    
    func handleMessage(_ message: BehaviorRelay<String>){
        message.subscribe { [weak self] event in
            guard let self = self else { return }
            guard let msg = event.element else { return }
            if !msg.isEmpty {
                self.view.makeToast(msg, position: .center)
            }
    
        }.disposed(by: disposeBag)
    }
 
}

